import { Injectable, NotFoundException, OnModuleInit } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './user.entity';

@Injectable()
export class UsersService implements OnModuleInit {
  constructor(
    @InjectRepository(User)
    private readonly repo: Repository<User>,
  ) {}

  /**
   * 模块初始化时调用，用于初始化数据库中的用户数据
   */
  async onModuleInit() {
    // Seed demo users if empty
    const count = await this.repo.count();
    if (count === 0) {
      const admin = this.repo.create({
        username: 'admin',
        password: 'admin123',
        email: 'admin@example.com',
        roles: ['admin'],
      });
      const alice = this.repo.create({
        username: 'alice',
        password: 'password',
        email: 'alice@example.com',
        roles: ['user'],
      });
      await this.repo.save([admin, alice]);
    }
  }

  /**
   * 获取所有用户，不包含密码字段
   */
  async findAll(): Promise<Omit<User, 'password'>[]> {
    const users = await this.repo.find();
    return users.map(({ password, ...rest }) => rest);
  }

  /**
   * 根据用户 ID 获取用户信息，不包含密码字段
   */
  async findOne(id: number): Promise<Omit<User, 'password'>> {
    const user = await this.repo.findOne({ where: { id } });
    if (!user) throw new NotFoundException(`User ${id} not found`);
    const { password, ...rest } = user;
    return rest;
  }

  /**
   * 根据用户名获取用户信息，不包含密码字段
   */
  async findByUsername(username: string): Promise<User | undefined> {
    const found = await this.repo.findOne({ where: { username } });
    return found ?? undefined;
  }

  /**
   * 创建新用户，默认角色为 'user'
   */ 
  async create(dto: CreateUserDto): Promise<Omit<User, 'password'>> {
    const user = this.repo.create({ roles: ['user'], ...dto });
    const saved = await this.repo.save(user);
    const { password, ...rest } = saved;
    return rest;
  }

  /**
   * 更新用户信息，不包含密码字段
   */
  async update(id: number, dto: UpdateUserDto): Promise<Omit<User, 'password'>> {
    const user = await this.repo.findOne({ where: { id } });
    if (!user) throw new NotFoundException(`User ${id} not found`);
    Object.assign(user, dto);
    const saved = await this.repo.save(user);
    const { password, ...rest } = saved;
    return rest;
  }

  /**
   * 删除用户
   */
  async remove(id: number): Promise<void> {
    const result = await this.repo.delete(id);
    if (result.affected === 0) throw new NotFoundException(`User ${id} not found`);
  }
}